package org.xmh.demo.account.action;

import java.io.PrintWriter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.personal.jdbc.PreparedStatementSetter;
import org.personal.jdbc.PreparedStatementSupport;
import org.personal.jdbc.RowMapper;
import org.personal.struts.action.LoginAware;
import org.xmh.demo.common.ConnectionUtil;
import org.xmh.demo.common.user.UserAuthBean;
import org.xmh.demo.entity.User;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

public class LoginAction extends ActionSupport implements Preparable,ServletResponseAware,SessionAware{

	private static final long serialVersionUID = -9158208132411058432L;
	private HttpServletResponse response;
	private Map<String,Object> session;
	private User user=new User();
	
	/**
	 * 登录
	 */
	public void login(){
		String responseResult=LoginAware.SUCCEED;
		UserAuthBean userauthbean=null;
		PrintWriter out = null;
		User userLogin=null;
		try {
			out = response.getWriter();
			
			if(session.containsKey(LoginAware.USER_SESSION_NAME)){
				userauthbean=(UserAuthBean)session.get(LoginAware.USER_SESSION_NAME);
			}else{
				userauthbean=new UserAuthBean();
			}
			//检查登录参数完整性,如果完整,则返回字符串:parameters full
			String checkResult=loginCheck(user);
			//登录参数完整
			if("parameters full".equals(checkResult)){
				//获得请求登录的用户
				userLogin=loginObject(user);
			}else{
				responseResult=checkResult;
			}
			//用户对象不存在
			if(userLogin==null){
				//登录失败
				responseResult=LoginAware.FAILURE;
				userauthbean.LOGIN_ERROR_SUBMIT_COUNT+=1;
			}else{
				userauthbean.setUser(user);
			}
			session.put(LoginAware.USER_SESSION_NAME,userauthbean);
			out.write(responseResult);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/** 登录输入检查
	 * @param user
	 * @return
	 */
	private String loginCheck(final User user){
		String name=user.getName();
		String password=user.getPassword();
		if(name==null||"".equals(name)){
			return LoginAware.NAME_IS_NULL;
		}else if(password==null||"".equals(password)){
			return LoginAware.PASSWORD_IS_NULL;
		}
		return "parameters full";
	}
	
	/** 获得请求登录用户对象,如果用户不存在,则返回NULL
	 * @param user 请求登录的用户对象
	 * @return
	 */
	@SuppressWarnings({ "unchecked"})
	private User loginObject(final User user){
		String sql="SELECT * FROM `USER` WHERE `name`=? AND `password`=?";
		PreparedStatementSupport pss = ConnectionUtil.init().getPreparedStatementSupport();
		List<User> userList=pss.query(sql,new PreparedStatementSetter(){
			public void setValues(PreparedStatement ps) throws SQLException {
				ps.setString(1,user.getName());
				ps.setString(2,user.getPassword());
			}},new RowMapper() {
				public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
					User user=new User();
					user.setName(rs.getString("name"));
					//user.setPassword(rs.getString("password"));
					user.setBirthday(rs.getDate("birthday"));
					user.setEmail(rs.getString("email"));
					user.setNationality(rs.getString("nationality"));
					return user;
				}
			});
		return userList.size()>0?userList.get(0):null;
	}
	
	
	
	
	
	/**
	 * @throws Exception
	 */
	public void prepareLogin() throws Exception {
		System.out.println("prepareLogin");
	}
	
	/* struts2 prepare 拦截器   实现 com.opensymphony.xwork2.Preparable 接口
	 * 向动作添加额外工作流处理的入口点,如为不同的动作添加不同的处理入口方法,格式为:prepare方法名,如同上一个方法
	 * (non-Javadoc)
	 * @see com.opensymphony.xwork2.Preparable#prepare()
	 */
	public void prepare() throws Exception {
		System.out.println("prepare");
	}
	
	
	
	
	
	
	



	public void setSession(Map<String, Object> session) {
		this.session=session;
	}
	public void setServletResponse(HttpServletResponse response) {
		this.response=response;
	}
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
}
